package com.maxverse.boot.web2image.service.impl;

import com.maxverse.boot.web2image.core.constant.TaskStatus;
import com.maxverse.boot.web2image.core.exception.Web2ImageException;
import com.maxverse.boot.web2image.core.model.dto.ScreenshotRequest;
import com.maxverse.boot.web2image.core.model.vo.TaskResponse;
import com.maxverse.boot.web2image.core.service.ScreenshotService;
import com.maxverse.boot.web2image.core.service.SystemConfigService;
import com.maxverse.boot.web2image.core.util.TaskIdGenerator;
import com.maxverse.boot.web2image.common.model.TaskMessage;
import com.maxverse.boot.web2image.queue.producer.TaskProducer;
import com.maxverse.boot.web2image.storage.entity.Task;
import com.maxverse.boot.web2image.storage.entity.TaskConfig;
import com.maxverse.boot.web2image.storage.file.FileStorage;
import com.maxverse.boot.web2image.storage.repository.TaskConfigRepository;
import com.maxverse.boot.web2image.storage.repository.TaskRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Slf4j
@Service
public class ScreenshotServiceImpl implements ScreenshotService {

    @Autowired
    private TaskRepository taskRepository;
    
    @Autowired
    private TaskConfigRepository taskConfigRepository;
    
    @Autowired
    private TaskProducer taskProducer;
    
    @Autowired
    private FileStorage fileStorage;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SystemConfigService configService;

    @Override
    @Transactional
    public TaskResponse createTask(ScreenshotRequest request) {
        // 使用系统默认配置
        if (request.getWidth() == null) {
            request.setWidth(Integer.parseInt(
                configService.getConfig("screenshot.default.width", "1920")));
        }
        if (request.getHeight() == null) {
            request.setHeight(Integer.parseInt(
                configService.getConfig("screenshot.default.height", "1080")));
        }
        if (request.getQuality() == null) {
            request.setQuality(Integer.parseInt(
                configService.getConfig("screenshot.default.quality", "90")));
        }
        
        // 生成任务ID
        String taskId = TaskIdGenerator.generate();
        
        // 创建任务记录
        Task task = new Task();
        task.setTaskId(taskId);
        task.setUrl(request.getUrl());
        task.setStatus(TaskStatus.PENDING);
        task.setWidth(request.getWidth());
        task.setHeight(request.getHeight());
        task.setFormat(request.getFormat());
        task.setQuality(request.getQuality());
        task.setCaptureMode(request.getCaptureMode());
        task.setCreateTime(LocalDateTime.now());
        task.setUpdateTime(LocalDateTime.now());
        
        // 保存任务
        task = taskRepository.save(task);
        
        // 确保事务提交后再发送消息
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                // 发送任务到队列
                TaskMessage message = new TaskMessage();
                message.setTaskId(taskId);
                message.setUrl(request.getUrl());
                message.setWidth(request.getWidth());
                message.setHeight(request.getHeight());
                message.setFormat(request.getFormat());
                message.setQuality(request.getQuality());
                message.setCaptureMode(request.getCaptureMode());
                
                taskProducer.sendTask(message);
            }
        });
        
        // 返回响应
        TaskResponse response = new TaskResponse();
        response.setTaskId(taskId);
        response.setStatus(TaskStatus.PENDING);
        return response;
    }

    @Override
    public TaskResponse getTaskStatus(String taskId) {
        Task task = taskRepository.findByTaskId(taskId)
                .orElseThrow(() -> new Web2ImageException("Task not found: " + taskId));
        
        TaskResponse response = new TaskResponse();
        response.setTaskId(taskId);
        response.setStatus(task.getStatus());
        response.setResultPath(task.getResultPath());
        response.setErrorMsg(task.getErrorMsg());
        return response;
    }

    @Override
    public byte[] getTaskResult(String taskId) {
        Task task = taskRepository.findByTaskId(taskId)
                .orElseThrow(() -> new Web2ImageException("Task not found: " + taskId));
        
        if (task.getStatus() != TaskStatus.SUCCESS) {
            throw new Web2ImageException("Task is not completed successfully: " + taskId);
        }
        
        if (task.getResultPath() == null) {
            throw new Web2ImageException("Task result not found: " + taskId);
        }
        
        return fileStorage.get(task.getResultPath());
    }

    @Override
    public Page<TaskResponse> getTasks(String taskId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createTime"));
        
        Page<Task> tasks;
        if (StringUtils.hasText(taskId)) {
            tasks = taskRepository.findByTaskIdContaining(taskId, pageable);
        } else {
            tasks = taskRepository.findAll(pageable);
        }
        
        return tasks.map(task -> {
            TaskResponse response = new TaskResponse();
            response.setTaskId(task.getTaskId());
            response.setUrl(task.getUrl());
            response.setStatus(task.getStatus());
            response.setResultPath(task.getResultPath());
            response.setErrorMsg(task.getErrorMsg());
            response.setFormat(task.getFormat());
            return response;
        });
    }

    @Override
    @Transactional
    public void deleteTask(String taskId) {
        Task task = taskRepository.findByTaskId(taskId)
                .orElseThrow(() -> new Web2ImageException("Task not found: " + taskId));
        
        // 如果有结果文件，删除文件
        if (task.getResultPath() != null) {
            try {
                fileStorage.delete(task.getResultPath());
            } catch (Exception e) {
                log.warn("Failed to delete result file: {}", task.getResultPath(), e);
            }
        }
        
        // 删除任务配置
        taskConfigRepository.deleteByTaskId(taskId);
        
        // 删除任务
        taskRepository.delete(task);
    }
} 